/*	
 *				
 *					ISNW ---- It is a war.It is not warcraft!
 *
 *
 *					Author:					zhoukeli(haxixi_keli)
 *					Filename:				isnwList.h
 *					CreateTime:				2008/12/06
 *					ModifyTime:				2008/12/06
 *
 */

#ifndef __ISNW_LIST_H__
#define __ISNW_LIST_H__

#include "isnwTypes.h"

namespace ISNW
{
namespace core
{
	template<typename T>
	class list
	{
	protected:
		struct list_node
		{
			list_node():prev(0),next(0){}

			list_node*		prev;
			list_node*		next;
			T				element;
		};

	public:
		//! default constructor
		list():head(0),End(0),size(0){}

		//! list iterator
		class iterator
		{
		public:
			iterator():current(0){}

		public:
			//! ++/-- operator
			iterator& operator ++ ()
			{
				current = current->next;
				return *this;
			}
			iterator& operator -- ()
			{
				current = current->prev;
				return *this;
			}

			iterator operator ++ (s32)
			{
				iterator ret = *this;
				current = current->next;
				return ret;
			}
			iterator operator -- (s32)
			{
				iterator ret = *this;
				current = current->prev;
				return ret;
			}

			T& operator * ()
			{
				return current->element;
			}

			iterator& operator += (s32 num)
			{
				if(num > 0)
				{
					while(num > 0 && current != 0)
					{
						current = current->next;
						--num;
					}
				}else{
					while(num < 0 && current != 0)
					{
						current = current->prev;
						++num;
					}
				}
				return *this;
			}

			iterator operator + (s32 num)
			{
				iterator ret = *this;
				ret += num;
				return ret;
			}

			iterator& operator -= (s32 num)
			{
				return (*this += -num);
			}

			iterator operator - (s32 num)
			{
				iterator ret = *this;
				ret -= num;
				return ret;
			}

			bool operator == (const iterator& other)
			{
				return (current == other.current);
			}

			bool operator != (const iterator& other)
			{
				return !(*this == other);
			}

			iterator& operator = (list_node* n)
			{
				current = n;
				return *this;
			}

		protected:
			iterator(list_node* begin):current(begin){}
			list_node*			current;
			friend class list;
		};

		bool empty() const
		{
			return head == 0;
		}

		void push_back(const T& element)
		{
			if(!head)
			{
				head = new list_node;
				head->element = element;
				End = head;
				size = 1;
			}
			else
			{
				list_node* tmp = new list_node;
				tmp->element = element;
				End->next = tmp;
				tmp->prev = End;
				End = tmp;
			}
		}

		iterator begin() const
		{
			return iterator(head);
		}

		iterator end() const
		{
			return iterator(0);
		}

		iterator erase(iterator& iter)
		{
			iterator retiterator = iter;
			++retiterator;

			if(iter.current)
			{
				if(iter.current == head)
				{
					head = iter.current->next;
				}
				else
				{
					iter.current->prev->next = iter.current->next;
				}
				
				if(iter.current == End)
				{
					End = iter.current->prev;
				}
				else
				{
					iter.current->next->prev = iter.current->prev;
				}
				delete iter.current;
			}
			
			iter.current = 0;
			--size;
			return retiterator;
		}

		void clear()
		{
			if(size == 0) return;

			list_node* bak = head->next;
			while(head !=End)
			{
				delete head;
				head = bak;
				bak = head->next;
			}
		}

	protected:
		list_node*			head;
		list_node*			End;
		u32					size;
	};

} // end namespace core
} // end namespace ISNW
#endif